#ifndef _OSG_PTR_HELPERS_H_
#define _OSG_PTR_HELPERS_H_

#include <OpenSG/OSGFieldContainerPtr.h>
#include <OpenSG/OSGAttachmentContainerPtr.h>
#include <OpenSG/OSGAttachmentPtr.h>
#include <OpenSG/OSGRefPtr.h>
#include <OpenSG/OSGNodePtr.h>

/** @name Meta functions for boost.python. */
//@{
namespace boost { namespace python
{

  template<typename B, typename C> struct pointee< osg::FCPtr<B,C> >
  {
     typedef typename OSG::FCPtr<B,C>::StoredObjectType type;
  };

  
  template <class B, class C>
  inline typename osg::FCPtr<B,C>::StoredObjectType*
     get_pointer(OSG::FCPtr<B,C> const& p)
  { return p.getCPtr(); }

  template<class B, class C> struct pointee< osg::RefPtr<osg::FCPtr<B,C> > >
  {
     typedef typename OSG::FCPtr<B,C>::StoredObjectType type;
  };

  template<class B, class C>
  inline typename osg::FCPtr<B,C>::StoredObjectType*
     get_pointer(osg::RefPtr<osg::FCPtr<B,C> > const & p)
  {
      return p.get().getCPtr();
  }
  
  
  // AttachmentPtr
  template<> struct pointee< osg::AttachmentPtr >
  {
     typedef osg::AttachmentPtr::StoredObjectType type;
  };
  
  inline osg::AttachmentPtr::StoredObjectType* get_pointer(osg::AttachmentPtr const& p)
  { return p.getCPtr(); }

  template<> struct pointee< osg::AttachmentRefPtr >
  {
     typedef osg::AttachmentPtr::StoredObjectType type;
  };

  inline osg::AttachmentPtr::StoredObjectType* get_pointer(osg::AttachmentRefPtr const & p)
  {
      return p.get().getCPtr();
  }

  // AttachmentContainerPtr
  template<> struct pointee< osg::AttachmentContainerPtr >
  {
     typedef osg::AttachmentContainerPtr::StoredObjectType type;
  };
  
  inline osg::AttachmentContainerPtr::StoredObjectType* get_pointer(osg::AttachmentContainerPtr const& p)
  { return p.getCPtr(); }

  template<> struct pointee< osg::AttachmentContainerRefPtr >
  {
     typedef osg::AttachmentContainerPtr::StoredObjectType type;
  };

  inline osg::AttachmentContainerPtr::StoredObjectType* get_pointer(osg::AttachmentContainerRefPtr const & p)
  {
      return p.get().getCPtr();
  }
  
  // Node
  template<> struct pointee<osg::NodePtr>
  {
     typedef osg::NodePtr::StoredObjectType type;
  };

  inline osg::Node* get_pointer(OSG::NodePtr const & p)
  {
      return p.getCPtr();
  }

  template <> struct pointee<osg::NodeRefPtr>
  {
     typedef osg::NodePtr::StoredObjectType type;
  };

  inline osg::Node* get_pointer(osg::NodeRefPtr const & p)
  {
      return p.get().getCPtr();
  }
}}
//@}

namespace pyopensg
{
//
// Helper templates for going to/from FCPtrs and ref ptrs
template<typename FCPTR>
osg::RefPtr<FCPTR> ToRefPtr(FCPTR& ptr)
{
   return osg::RefPtr<FCPTR>(ptr);
}

template<typename FCPTR>
FCPTR ToFcPtr(osg::RefPtr<FCPTR>& ptr)
{
   return ptr.get();
}

}

#endif

